package com.xtt._01_java8;

import org.junit.Test;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;

/**
 * @Author xtt.
 * @Description: java8 新的日期时间API
 * @Date:Create in 2017/9/20 0020 下午 23:12
 * @Modify By:
 */
public class DateTimeTest {
    /*
    *   java.time包：这是新的Java日期/时间API的基础包，所有的主要基础类都是这个包的一部分，
*       如：LocalDate, LocalTime, LocalDateTime, Instant, Period, Duration等等。
*       所有这些类都是不可变的和线程安全的，在大多数情况下，这些类足够应付常见需求。
    *
        java.time.chrono包：这个包为非ISO的日历系统定义了一些泛化的API，我们可以扩展AbstractChronology类来创建自己的日历系统。

        java.time.format包：这个包包含能够格式化和解析日期时间对象的类，
        在绝大多数情况下，我们不应该直接使用它们，因为java.time包中相应的类已经提供了格式化和解析的方法。

        java.time.temporal包：这个包包含一些时态对象，我们可以用其找出关于日期/时间对象的某个特定日期或时间，
        比如说，可以找到某月的第一天或最后一天。你可以非常容易地认出这些方法，因为它们都具有“withXXX”的格式。

        java.time.zone包：这个包包含支持不同时区以及相关规则的类。
        */
    @Test
    public void testLocalDate(){

        LocalDate now = LocalDate.now();
        System.out.println(now);//2017-09-20

        LocalDate parse = LocalDate.parse("2017-09-20");
        System.out.println(parse);

        // 通过传入的参数创建LocalDate对象
        LocalDate firstDay_2014 = LocalDate.of(2014, Month.JANUARY, 1);
        System.out.println("指定日期=" + firstDay_2014);//指定日期=2014-01-01

        // 根据有效输入创建日期，以下代码会抛异常，无效输入，2014年2月没有29日
        // LocalDate feb29_2014 = LocalDate.of(2014, Month.FEBRUARY, 29);
        // Exception in thread "main" java.time.DateTimeException:
        // Invalid date 'February 29' as '2014' is not a leap year

        // 获取不同时区的日期 "Asia/Kolkata", you can get it from ZoneId javadoc
        LocalDate todayKolkata = LocalDate.now(ZoneId.of("Asia/Kolkata"));
        System.out.println("当前印度标准日期=" + todayKolkata);//当前印度标准日期=2017-09-20

        // java.time.zone.ZoneRulesException: Unknown time-zone ID: IST
        // LocalDate todayIST = LocalDate.now(ZoneId.of("IST"));

        // 从基准日期获取日期  例如： 01/01/1970
        LocalDate dateFromBase = LocalDate.ofEpochDay(365);//基准日期的第365天= 1971-01-01
        System.out.println("基准日期的第365天= " + dateFromBase);

        //2014年的第一百天
        LocalDate hundredDay2014 = LocalDate.ofYearDay(2014, 100);
        System.out.println("2014年的第一百天=" + hundredDay2014);//2014年的第一百天=2014-04-10
    }

    @Test
    public void testLocalTime(){
        // Current Time
        LocalTime time = LocalTime.now();
        System.out.println("Current Time=" + time);//Current Time=23:24:22.417

        // Creating LocalTime by providing input arguments
        LocalTime specificTime = LocalTime.of(12, 20, 25, 40);
        System.out.println("Specific Time of Day=" + specificTime);//Specific Time of Day=12:20:25.000000040

        // Try creating time by providing invalid inputs
        // LocalTime invalidTime = LocalTime.of(25,20);
        // Exception in thread "main" java.time.DateTimeException:
        // Invalid value for HourOfDay (valid values 0 - 23): 25

        // Current date in "Asia/Kolkata", you can get it from ZoneId javadoc
        LocalTime timeKolkata = LocalTime.now(ZoneId.of("Asia/Kolkata"));
        System.out.println("Current Time in IST=" + timeKolkata);//Current Time in IST=20:54:22.417

        // java.time.zone.ZoneRulesException: Unknown time-zone ID: IST
        // LocalTime todayIST = LocalTime.now(ZoneId.of("IST"));

        // Getting date from the base date i.e 01/01/1970
        LocalTime specificSecondTime = LocalTime.ofSecondOfDay(10000);
        System.out.println("10000th second time= " + specificSecondTime);//10000th second time= 02:46:40
    }

    /**
     * yyyy-MM-dd-HH-mm-ss.zzz
     */
    @Test
    public void testLocaDataTime() {
        // Current Date
        LocalDateTime today = LocalDateTime.now();
        System.out.println("Current DateTime=" + today);//2017-09-20T23:27:01.511

        // Current Date using LocalDate and LocalTime
        today = LocalDateTime.of(LocalDate.now(), LocalTime.now());
        System.out.println("Current DateTime=" + today);//2017-09-20T23:27:01.511

        // Creating LocalDateTime by providing input arguments
        LocalDateTime specificDate = LocalDateTime.of(2014, Month.JANUARY, 1, 10, 10, 30);
        System.out.println("Specific Date=" + specificDate);//2014-01-01T10:10:30

        // Try creating date by providing invalid inputs
        // LocalDateTime feb29_2014 = LocalDateTime.of(2014, Month.FEBRUARY, 28,
        // 25,1,1);
        // Exception in thread "main" java.time.DateTimeException:
        // Invalid value for HourOfDay (valid values 0 - 23): 25

        // Current date in "Asia/Kolkata", you can get it from ZoneId javadoc
        LocalDateTime todayKolkata = LocalDateTime.now(ZoneId.of("Asia/Kolkata"));
        System.out.println("Current Date in IST=" + todayKolkata);//2017-09-20T20:57:01.511

        // java.time.zone.ZoneRulesException: Unknown time-zone ID: IST
        // LocalDateTime todayIST = LocalDateTime.now(ZoneId.of("IST"));

        // Getting date from the base date i.e 01/01/1970
        LocalDateTime dateFromBase = LocalDateTime.ofEpochSecond(10000, 0, ZoneOffset.UTC);
        System.out.println("10000th second time from 01/01/1970= " + dateFromBase);//1970-01-01T02:46:40
    }

    /**
     * Instant类是用在机器可读的时间格式上的，它以Unix时间戳的形式存储日期时间，
     */
    @Test
    public void testInstants() {
        // Current timestamp
        Instant timestamp = Instant.now();//2017-09-20T15:29:41.364Z
        System.out.println("Current Timestamp = " + timestamp);

        // Instant from timestamp
        Instant specificTime = Instant.ofEpochMilli(timestamp.toEpochMilli());
        System.out.println("Specific Time = " + specificTime);//2017-09-20T15:29:41.364Z

        // Duration example
        Duration thirtyDay = Duration.ofDays(30);
        System.out.println(thirtyDay);//PT720H
    }

    /**
     * 日期加减工具方法
     */
    @Test
    public void testDataUtilAPI() {
        LocalDate today = LocalDate.now();

        // Get the Year, check if it's leap year
        System.out.println("Year " + today.getYear() + " is Leap Year? " + today.isLeapYear());
        //Year 2017 is Leap Year? false

        // Compare two LocalDate for before and after
        System.out.println("Today is before 01/01/2015? " + today.isBefore(LocalDate.of(2015, 1, 1)));
        //Today is before 01/01/2015? false

        // Create LocalDateTime from LocalDate
        System.out.println("Current Time=" + today.atTime(LocalTime.now()));
        //Current Time=2017-09-20T23:33:51.751

        // plus and minus operations
        System.out.println("10 days after today will be " + today.plusDays(10));
        System.out.println("3 weeks after today will be " + today.plusWeeks(3));
        System.out.println("20 months after today will be " + today.plusMonths(20));

        System.out.println("10 days before today will be " + today.minusDays(10));
        System.out.println("3 weeks before today will be " + today.minusWeeks(3));
        System.out.println("20 months before today will be " + today.minusMonths(20));

        LocalDateTime localDateTime = today.atTime(LocalTime.now());
        System.out.println(localDateTime);
        System.out.println(localDateTime.plusDays(2));
        System.out.println(localDateTime.plusHours(2));
        System.out.println(localDateTime.plusMinutes(2));
        System.out.println(localDateTime.plusNanos(2));
        System.out.println(localDateTime.plusSeconds(2));
        System.out.println(localDateTime.plusWeeks(2));
        System.out.println(localDateTime.plusMonths(2));
        System.out.println(localDateTime.plusYears(2));
        // Temporal adjusters for adjusting the dates
        System.out.println("First date of this month= " + today.with(TemporalAdjusters.firstDayOfMonth()));
        LocalDate lastDayOfYear = today.with(TemporalAdjusters.lastDayOfYear());
        System.out.println("Last date of this year= " + lastDayOfYear);

        Period period = today.until(lastDayOfYear);
        System.out.println("Period Format= " + period);
        System.out.println("Months remaining in the year= " + period.getMonths());
    }

    @Test
    public void testDataFormat() {
        // Format examples
        LocalDate date = LocalDate.now();
        // default format
        System.out.println("Default format of LocalDate=" + date);//Default format of LocalDate=2017-09-20
        // specific format
        System.out.println(date.format(DateTimeFormatter.ofPattern("d::MMM::uuuu")));//20::九月::2017
        System.out.println(date.format(DateTimeFormatter.BASIC_ISO_DATE));//20170920

        LocalDateTime dateTime = LocalDateTime.now();
        // default format
        System.out.println("Default format of LocalDateTime=" + dateTime);//Default format of LocalDateTime=2017-09-20T23:41:29.703
        // specific format
        System.out.println(dateTime.format(DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss")));//20::九月::2017 23::41::29
        System.out.println(dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));//2017-09-20 23:43:56
        System.out.println(dateTime.format(DateTimeFormatter.BASIC_ISO_DATE));//20170920

        Instant timestamp = Instant.now();
        // default format
        System.out.println("Default format of Instant=" + timestamp);//ault format of Instant=2017-09-20T15:41:29.703Z

        // Parse examples
        LocalDateTime dt = LocalDateTime.parse("27::四月::2014 21::39::48",
                DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss"));
        System.out.println("Default format after parsing = " + dt);//Default format after parsing = 2014-04-27T21:39:48
    }
}
